﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using ExpertSystem.Interfaces;
using ExpertSystem.Views;

namespace ExpertSystem.Domains
{
    public class Rule : IRule
    {
        public Rule(string name, string comments, IVariable reternibleValue, string value)
        {
            _name = name;
            _value = value;
            _reternibleValue = reternibleValue;
            _comments = comments;
            _conjuncts = new List<IConjunct>();
        }
        
        #region Приватные поля

        private string _name;
        private List<IConjunct> _conjuncts;
        private string _comments;
        private IVariable _reternibleValue;
        private string _value;
        private bool _isACtiv = false;
        private bool _try_to_resolve = false;
        public event EventHandler RuleActivated;
        private IVariable _returnable_value;

        #endregion

        #region Implementation of IRule

        public string Name
        {
            get { return _name; }
            private set { _name = value; }
        }

        public List<IConjunct> Conjuncts
        {
            get { return _conjuncts; }
            private set { _conjuncts = value; }
        }

        public string Comments
        {
            get { return _comments; }
        }

        public bool CanBeResolved()
        {
            return !_conjuncts.Any(con => !con.CanBeResolved()) && !_try_to_resolve;
        }

        public bool IsActivated()
        {
            return _try_to_resolve;
        }

        public bool CanBeAvtivated()
        {
            return !_conjuncts.Any(con => !con.CanReturnTrueValue());
        }

        public void ReturnVariable(IVariable variable)
        {
            _returnable_value = variable;
        }

        public void EditRule()
        {
            EditRuleView editRuleView = new EditRuleView(this);
            editRuleView.ShowDialog();
        }

        public void Resolve()
        {
            _try_to_resolve = true;
            foreach (IConjunct conjunct in _conjuncts.Where(x => x.CanBeResolved()))
            {
                conjunct.Resolve();
            }
            if(!_conjuncts.Any(x => !x.Value()))
            {
                if (_returnable_value == null)
                {
                    if (_reternibleValue.AppendableValue)
                    {
                        if (_reternibleValue.Value != null)
                        {
                            _reternibleValue.Value += "," + _value;
                        }
                        else
                        {
                            _reternibleValue.Value += _value;
                        }
                        
                    }
                    else
                    {
                        _reternibleValue.Value = _value;
                    }
                }
                else
                {
                    _reternibleValue.Value = _returnable_value.Value;
                }
                
                _isACtiv = true;
                RuleActivated(this, null);
            }
            _reternibleValue.TryToResolve();
        }

        public bool Activated()
        {
            return _isACtiv;
        }

        public bool IsReternedValueEquals(IVariable variable)
        {
            return _reternibleValue.Equals(variable);
        }

        public IVariable ReternebleVariable
        {
            get { return _reternibleValue; }
        }

        public IVariable CanNotBeResolvedVariable()
        {
            return Conjuncts.First(con => !con.CanBeResolved()).CanNotResolvedVariable();
        }

        #endregion
    }
}
